﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Petzold.Media3D;
using System.Windows.Media.Media3D;
using Microsoft.Win32;
using System.Configuration;
using GeometryViz3D.Model;
using CoreMVVM.ViewModels;
using System.ComponentModel;
using GeometryViz3D.ViewModels;
using GeometryViz3D.Services;
using CoreMVVM.Services;

namespace GeometryViz3D.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        MainWindowViewModel m_viewModel;

        ControlPanel m_controlPanel;

        public MainWindow()
        {
            ViewModelBase.ServiceProvider.RegisterService<IUIVisualizerService>(new UIVisualizerService());
            IUIVisualizerService service = ViewModelBase.ServiceProvider.GetService<IUIVisualizerService>();

            service.Register("AddLineDialog", typeof(AddLineDialog));
            service.Register("AddPointDialog", typeof(AddPointDialog));
            //service.Register("EditModelDialog", typeof(EditModelDialog));

            m_viewModel = new GeometryViz3D.ViewModels.MainWindowViewModel(
                new ServicesFactory());
            
            this.DataContext = m_viewModel;

            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            UpdateMRUMenuItems();

            m_controlPanel = new ControlPanel();

            m_controlPanel.Left = this.Left + this.ActualWidth - m_controlPanel.Width - 1;
            m_controlPanel.Top = this.Top + SystemParameters.CaptionHeight;
            m_controlPanel.Show();

            menuItemShowControlPanel.IsEnabled = false;

            m_controlPanel.Owner = this;
            m_controlPanel.Closing += new System.ComponentModel.CancelEventHandler(ControlPanel_Closing);

            m_controlPanel.Bind(viewport.AxisX, AxisAngleRotation3D.AngleProperty, ControlPanel.SliderId.AxisX);
            m_controlPanel.Bind(viewport.AxisY, AxisAngleRotation3D.AngleProperty, ControlPanel.SliderId.AxisY);
            m_controlPanel.Bind(viewport.AxisZ, AxisAngleRotation3D.AngleProperty, ControlPanel.SliderId.AxisZ);
            m_controlPanel.Bind(viewport, G3DViewport.DistanceProperty, ControlPanel.SliderId.Distance);

            m_viewModel.PropertyChanged += ViewModelPropertyChanged;
        }

        private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "Model":
                    ShowModel();
                    break;

                case "ModelFileName":
                    SetWindowTitle();
                    SetMostRecentModel();
                    break;
            }
        }

        private void ShowModel()
        {
            viewport.Model = m_viewModel.Model;

            m_controlPanel.MinDistance = this.viewport.Extent / 8;
            m_controlPanel.MaxDistance = this.viewport.Extent * 8;
            m_controlPanel.Distance = this.viewport.Extent * 4;

            m_controlPanel.Left = this.Left + this.ActualWidth - m_controlPanel.Width - 1;
            m_controlPanel.Top = this.Top + SystemParameters.CaptionHeight;

            m_controlPanel.Show();

            menuItemShowControlPanel.IsEnabled = true;
            menuItemShowControlPanel.Header = "Hide Control Panel";

            SetWindowTitle();
        }

        private void SetWindowTitle()
        {
            this.Title = m_viewModel.Model.FileName + " - Geometry 3D";
        }

        private void ShowControlPanel_Click(object sender, RoutedEventArgs e)
        {
            if (m_controlPanel.IsVisible)
            {
                m_controlPanel.Hide();
                menuItemShowControlPanel.Header = "Show Control Panel";
            }
            else
            {
                m_controlPanel.Show();
                menuItemShowControlPanel.Header = "Hide Control Panel";
            }
        }

        private void ControlPanel_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;

            m_controlPanel.Hide();
            menuItemShowControlPanel.Header = "Show Control Panel";
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
#if false
            if (m_controlPanel != null)
            {
                m_controlPanel.Left = this.Left + this.ActualWidth - m_controlPanel.Width;
                m_controlPanel.Top = this.Top + SystemParameters.CaptionHeight;
            }
#endif
        }

        #region Recent Models

        private void UpdateMRUMenuItems()
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            MRUSection mruSection = MRUSection.GetSection(config);

            menuItemRecentModels.Items.Clear();

            if (!string.IsNullOrEmpty(mruSection.Models))
            {
                string[] models = mruSection.Models.Split(';');

                foreach (string model in models)
                {
                    MenuItem mi = new MenuItem() { Header = model };
                    mi.Click += new RoutedEventHandler(menuItemRecentModel_Click);
                    menuItemRecentModels.Items.Add(mi);
                }
            }
        }

        private void menuItemRecentModel_Click(object sender, EventArgs e)
        {
            if (sender is MenuItem)
            {
                MenuItem mi = (MenuItem)sender;
                m_viewModel.LoadModel(mi.Header.ToString());
            }
        }

        private void SetMostRecentModel()
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            MRUSection mruSection = MRUSection.GetSection(config);

            mruSection.OnOpenModel(m_viewModel.Model.FileName);
            mruSection.SectionInformation.ForceSave = true;
            config.Save();

            UpdateMRUMenuItems();
        }

        #endregion
    }
}
